﻿
using Ldt.DataEngine.RuleAssemble;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.CommHelp;
using LdtJudge.DataEngine.Common.StringAssemble;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.Data;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.SysCommon;
using LdtJudge.DataEngine.Model.DataModel.SystemtableModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using LdtJudge.DataEngine.Model.XMLConfigModel.DisputeFocusModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.CaseExtract.FocusDispute
{
    /// <summary>
    /// 争议焦点获取
    /// </summary>
    public class FocusDisputeClass
    {
        public List<DataModel> OptimizationDataList = new List<DataModel>();
        private DALSYS_Express_Source dalRegexSource = new DALSYS_Express_Source();
        private GetSysCaseCause dALSYS_CaseCause = new GetSysCaseCause();
        private DataSoursModel dataSoursModel = new DataSoursModel();
        private SituationExpressAdd situationExpress = new SituationExpressAdd();
        private DataContext dataContext;
        private string moudleName;
        public FocusDisputeClass(DataContext context, string _moudleName)
        {
            this.dataContext = context;
            moudleName = _moudleName;
        }

        public void Start(string xmlconfig)
        {
            dataSoursModel = dataContext.DataLayerAns.AnalysisResultsDataModel;
            OptimizationDataList = dataSoursModel.dataModelList;
            //争议焦点内容
            DisputeFocusDelies(xmlconfig);
        }

        /// <summary>
        /// 争议焦点原文中推导出争议焦点内容
        /// </summary>
        public void DisputeFocusDelies(string xmlconfig)
        {
            DisputeFocusConfigModel disputeFocusConfigModel = XmlUtility.DeserializeToObject<DisputeFocusConfigModel>(xmlconfig);
            if (disputeFocusConfigModel != null)
            {
                var casetypelist = disputeFocusConfigModel.disputeFocusCaseTypeList.FirstOrDefault(a => a.value.ToLower() == dataContext.DataLayerAns.CaseType.ToLower());
                if (casetypelist != null)
                {
                    var doctypeList = casetypelist.disputeFocusDocTypeList.FirstOrDefault(a => a.value.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower());
                    if (doctypeList != null)
                    {
                        if (dataContext.DataLayerAns.CaseCausesList.Count == 0)
                        { 
                            return;
                        }
                        string cc_id = dataContext.DataLayerAns.CaseCausesList[0].CC_ID;
                        //通过配置的根节点路劲获取争议焦点节点DataModel
                        var disputeModel = XmlUtility.ConditionFirstOrDefaultDataModel(OptimizationDataList, "", doctypeList.focusGetPath);
                        if (disputeModel!=null && doctypeList.disputeFocusModelList!=null && doctypeList.disputeFocusModelList.Any())
                        {
                            foreach (var disputeFocusModel in doctypeList.disputeFocusModelList)
                            {
                                if(!string.IsNullOrWhiteSpace(disputeFocusModel.paragraphCode))
                                {
                                    var paragraphCodeList = disputeFocusModel.paragraphCode.Split(',').ToList();
                                    foreach (var paragraphCode in paragraphCodeList)
                                    {
                                        if(!string.IsNullOrWhiteSpace(paragraphCode.Trim()))
                                        {
                                            
                                            string argumentFocusNodeID = string.Empty;
                                            List<SYS_CaseCause> machtdata = GetArgumentFocusType(cc_id, ref argumentFocusNodeID);
                                            var duanluoList = dataContext.DataLayerAns.Duanluos.Where(x => x.Duanluobianhao == paragraphCode.Trim()).Select(x=>x.Duanluoneirong.Replace(@"\r", "").Replace(@"\n", "")).ToList();
                                            string orignalText = string.Join(' ', duanluoList);
                                            orignalText=Regex.Replace(orignalText, @"[\r\n]", "");
                                            orignalText = Regex.Replace(orignalText, @"[\r]", "");
                                            if (machtdata != null)
                                            {
                                                List<string> afd_typeids = MatchArgumentFocusList(dataContext.DataLayerAns.SourceCode, argumentFocusNodeID, orignalText, machtdata, paragraphCode);
                                                if (afd_typeids!=null && afd_typeids.Any())
                                                {
                                                    foreach (var afd_typeid in afd_typeids)
                                                    {
                                                        DataModel disputeDetailData = new DataModel();
                                                        disputeDetailData.ID = Snowflake.Instance().GetId().ToString();
                                                        disputeDetailData.ParentId = disputeModel.ID;
                                                        disputeDetailData.Name = "争议焦点详情";
                                                        disputeDetailData.XmlPath = $"{disputeModel.XmlPath}/争议焦点详情";
                                                        SourceData sourceData = new SourceData();
                                                        Source sourceModel = new Source();
                                                        sourceModel.ExtValue = "";
                                                        sourceModel.IsCheck = "1";
                                                        sourceModel.OriginalText = "";
                                                        sourceModel.ParagraphCode = paragraphCode;
                                                        sourceModel.SaveValue = "";
                                                        sourceModel.SourceCode = dataContext.DataLayerAns.SourceCode;
                                                        sourceModel.SourceID = dataContext.DataLayerAns.SF_ID;
                                                        sourceModel.SourceFLID = dataContext.DataLayerAns.FL_ID;
                                                        sourceData.sourceList = new List<Source>();
                                                        sourceData.sourceList.Add(sourceModel);
                                                        disputeDetailData.sourceData = sourceData;
                                                        disputeDetailData.AttributesList = new List<AttributeInfo>();
                                                        string ccname = machtdata.FirstOrDefault(a => a.CC_ID == afd_typeid).CC_Name;
                                                        AddAttrAttribute("争议焦点内容", ccname, disputeDetailData);
                                                        AddAttrAttribute("争议焦点ID", afd_typeid, disputeDetailData);
                                                        AddAttrAttribute("争议焦点原文", orignalText, disputeDetailData);
                                                        AddAttrAttribute("争议焦点系统推送方式", disputeFocusModel.value, disputeDetailData);
                                                        AddAttrAttribute("争议焦点获取来源", "analysiswrodparseservice", disputeDetailData);
                                                        AddAttrAttribute("争议焦点获取方式", "1", disputeDetailData);
                                                        dataContext.InteractiveShow.LogShow("争议焦点获取来源添加"+ afd_typeid);
                                                        if (!string.IsNullOrWhiteSpace(disputeFocusModel.JudgeReasonParagraphCode))
                                                        {
                                                            List<string> reasonList = disputeFocusModel.JudgeReasonParagraphCode.Split(",").ToList();
                                                            foreach (var reaseon in reasonList)
                                                            {
                                                                string reasonnodeId = "";
                                                                string resultnodeId = RefereeDisputFourus(afd_typeid, reaseon, out reasonnodeId);
                                                                GetSysCaseCause getSysCaseCause = new GetSysCaseCause();
                                                                if (!string.IsNullOrWhiteSpace(reasonnodeId) && !string.IsNullOrWhiteSpace(resultnodeId))
                                                                {
                                                                    var reasonnodeModel = getSysCaseCause.GetModel(reasonnodeId);
                                                                    AddAttrAttribute("裁判理由ID", reasonnodeId, disputeDetailData);
                                                                    if (reasonnodeModel != null)
                                                                    {
                                                                        AddAttrAttribute("裁判理由内容", reasonnodeModel.CC_Name, disputeDetailData);
                                                                    }
                                                                    var resultnodeModel = getSysCaseCause.GetModel(reasonnodeId);
                                                                    AddAttrAttribute("支持结果ID", resultnodeId, disputeDetailData);
                                                                    if (resultnodeModel != null)
                                                                    {
                                                                        AddAttrAttribute("支持结果内容", resultnodeModel.CC_Name, disputeDetailData);
                                                                    }
                                                                    string ms_id;
                                                                    if (!string.IsNullOrWhiteSpace(resultnodeId))
                                                                    {
                                                                        ms_id = situationExpress.GetGroupSituationID(resultnodeId, 1, "1", null);
                                                                    }
                                                                    else
                                                                    {
                                                                        ms_id = situationExpress.GetGroupSituationID(afd_typeid, 1, "1", null);
                                                                    }
                                                                    var model = situationExpress.GetGroupExpressIDModel(ms_id);
                                                                    AddAttrAttribute("说理表述ID", model.EW_ID, disputeDetailData);
                                                                    AddAttrAttribute("说理表述", model.EW_Content, disputeDetailData);
                                                                }
                                                            }
                                                        }
                                                        OptimizationDataList.Add(disputeDetailData);
                                                    }
                                                    
                                                }
                                            }
                                            
                                        }
                                    }
                                    
                                }
                            }
                        }
                        if (dataContext.DataLayerAns.AnalysisResultsXml == null)
                        {
                            dataContext.DataLayerAns.AnalysisResultsXml = new XmlDocument();
                        }
                        dataContext.DataLayerAns.AnalysisResultsXml = XmlUtility.DataModelByXml(OptimizationDataList);
                    }
                }
            }

        }
        /// <summary>
        /// 根据案由ID，获取需要匹配的争议焦点集合数据
        /// </summary>
        /// <param name="causeID">案由ID</param>
        /// <returns></returns>
        private List<SYS_CaseCause> GetArgumentFocusType(string causeID, ref string argumentFocusNodeID)
        {
            List<SYS_CaseCause> caseCauseTb = dALSYS_CaseCause.GetCaseCauseByParentid(causeID);
            if (caseCauseTb.Count > 0)
            {
                argumentFocusNodeID = LdFormat.ObjectToString(caseCauseTb[0].CC_ID);
                return dALSYS_CaseCause.GetCaseCauseByAllParentId(caseCauseTb[0].CC_ParentID);
            }
            return null;
        }

        /// <summary>
        ///裁判理获取
        /// </summary>
        /// <param name="argumentTypeID">争议焦点类型</param>
        /// <returns></returns>
        public string RefereeDisputFourus(string argumentTypeID,string paragraphCode, out string reasonnodeId)
        {

            return MatchArgumentResultNodeId(dataContext.DataLayerAns.SourceCode, argumentTypeID, paragraphCode,out reasonnodeId);
        }
        
        /// <summary>
        /// 获取匹配的争议结果结点ID
        /// </summary>
        /// <param name="sourceName">卷宗ID</param>
        /// <param name="argumentTypeID">争议类型ID</param>
        /// <returns>匹配裁判结果ID</returns>
        private string MatchArgumentResultNodeId(string sourceName, string argumentTypeID,string paragraphCode, out string reasonnodeId)
        {
            reasonnodeId = string.Empty;         //争议原因ID
            string resultnodeId = string.Empty;

            //001.匹配争议焦点原因结点
            string strSQL = "select * from SYS_CaseCause where AllParentId like '%," + argumentTypeID + ",%' and CC_NodeType='17'";
            List<SYS_CaseCause> reasonTb = dALSYS_CaseCause.GetCaseCauseByAllParentIds(argumentTypeID).Where(a => a.CC_NodeType == 17).ToList();
            foreach (SYS_CaseCause orow in reasonTb)
            {
                string sonArgumentReasonID = LdFormat.ObjectToString(orow.CC_ID);
                string sonArgumentReasonName = LdFormat.ObjectToString(orow.CC_Name);

                //获取不同标签下，配置的不同段落来源及相应的提取正则。。
                IList<MSYS_Express_Source> mSourceArr = dalRegexSource.GetListArray(sonArgumentReasonID, sourceName,paragraphCode);
                if (mSourceArr.Count == 0)
                    continue;

                MSYS_Express_Source useExtractSource = mSourceArr[0];

                bool isMatch = false;
                if (useExtractSource.IsEvidenceMatch == 1)
                {

                }
                else
                {
                    //获取关联当前正则的所有逻辑段。
                    var relatParagraph = from item in mSourceArr where (item.CC_RegexInfoCode == useExtractSource.CC_RegexInfoCode) select item.Source_ParagraphID;
                    //相关段落文本
                    string relatParagraphText = this.GetJoinParagraphText(relatParagraph.ToList<string>());
                    //争议原因，要从相关逻辑段中进行匹配提取。
                    isMatch = RuleParseClass.IsMatchsp(useExtractSource.CC_RegexInfoCode, relatParagraphText);
                }

                if (isMatch)
                {
                    reasonnodeId = sonArgumentReasonID;
                    break;
                }
            }
            //002.匹配争议焦点结果结点
            if (reasonnodeId != string.Empty)
            {
                List<SYS_CaseCause> resultNodeTb = dALSYS_CaseCause.GetCaseCauseByParentid(reasonnodeId).Where(a => a.CC_NodeType == 9 || a.CC_NodeType == 22).ToList();
                if (resultNodeTb.Count > 0)
                {
                    //结果结点，不需要匹配，是由原因结点推导而来的。
                    resultnodeId = LdFormat.ObjectToString(resultNodeTb[0].CC_ID);
                    string resultNodeName = LdFormat.ObjectToString(resultNodeTb[0].CC_Name);
                }
            }

            return resultnodeId;
        }

        /// <summary>
        /// 获取多个段落的文本拼接
        /// </summary>
        /// <param name="paragraphCode">段落编号列表</param>
        /// <returns>段落内容</returns>
        private string GetJoinParagraphText_new(IList<string> paragraphCode)
        {
            StringBuilder allParagrphText = new StringBuilder();

            return allParagrphText.ToString();
        }

        /// <summary>
        /// 获取多个段落的文本拼接
        /// </summary>
        /// <param name="paragraphCode">段落编号列表</param>
        /// <returns>段落内容</returns>
        private string GetJoinParagraphText(IList<string> paragraphCode)
        {
            StringBuilder allParagrphText = new StringBuilder();
            foreach (string code in paragraphCode)
            {
                foreach (var parag in dataContext.DataLayerAns.Duanluos.Where(a => a.Duanluobianhao.ToLower() == code.ToLower()))
                {
                    if (allParagrphText.ToString() != "")
                        allParagrphText.Append("\r");

                    allParagrphText.Append(parag.Duanluoneirong);
                }
            }
            return allParagrphText.ToString();
        }
        /// <summary>
        /// 转换出数据源实体
        /// </summary>
        /// <returns></returns>
        public DataSoursModel GetDataSoursModel(XmlDocument xmlDocument)
        {
            DataSoursModel soursModel = new DataSoursModel();
            soursModel = XmlUtility.DeserializeToObject<DataSoursModel>(xmlDocument.OuterXml.Replace("&#x", ""));
            foreach (DataModel dataModel in soursModel.dataModelList)
            {
                dataModel.XmlPath = dataModel.XmlPath.Replace("\\", "/");
            }
            return soursModel;
        }



        /// <summary>
        /// 根据文书类型和需要匹配的节点ID将内容进行匹配获取争议焦点类型
        /// </summary>
        /// <param name="SourceName">文书类型</param>
        /// <param name="CC_ParentID">节点ID</param>
        /// <param name="originalText">原文</param>
        /// <param name="MatchData">节点的数据集合</param>
        /// <returns></returns>
        private string MatchArgumentFocus(string SourceName, string CC_ParentID, string originalText, List<SYS_CaseCause> MatchData,string paragraphCode)
        {
            //获取子争议焦点类型
            List<SYS_CaseCause> sonRows = MatchData.Where(a => a.CC_ParentID == CC_ParentID).ToList();
            foreach (SYS_CaseCause oRow in sonRows)
            {
                string sonArgumentTypeID = LdFormat.ObjectToString(oRow.CC_ID);
                string sonArgumentTypeName = LdFormat.ObjectToString(oRow.CC_Name);
                int cc_NodeType = LdFormat.ObjectToInt(oRow.CC_NodeType);        //结点类型(15:虚拟点；16：争议焦点类型)

                if (cc_NodeType == 15)
                {
                    string secdSonMatchID = MatchArgumentFocus(SourceName, sonArgumentTypeID, originalText, MatchData, paragraphCode);
                    //有子级匹配时，返回子级匹配ID；
                    //无子级匹配时，返回当前匹配ID；
                    if (secdSonMatchID != string.Empty)
                        return secdSonMatchID;
                }
                else
                {
                    //获取不同标签下，配置的不同段落来源及相应的提取正则。。
                    IList<MSYS_Express_Source> MSourceArr;
                    MSourceArr = dalRegexSource.GetListArray(sonArgumentTypeID, SourceName, paragraphCode);
                    bool isMatch = false;
                    foreach (MSYS_Express_Source useExtractSource in MSourceArr)
                    {
                        isMatch = (useExtractSource == null) ? false : RuleParseClass.IsMatchs(useExtractSource.CC_RegexInfoCode, originalText);
                        if (isMatch)//这里表示如果能够匹配到，则进行停止循环匹配
                            break;
                    }

                    if (isMatch)
                    {
                        string secdSonMatchID = MatchArgumentFocus(SourceName, sonArgumentTypeID, originalText, MatchData, paragraphCode);
                        if (secdSonMatchID == string.Empty)
                            return sonArgumentTypeID;
                        else
                            return secdSonMatchID;
                    }
                }
            }
            //无子匹配时，返回空的匹配ID；
            return string.Empty;
        }

        /// <summary>
        /// 根据文书类型和需要匹配的节点ID将内容进行匹配获取争议焦点类型
        /// </summary>
        /// <param name="SourceName">文书类型</param>
        /// <param name="CC_ParentID">节点ID</param>
        /// <param name="originalText">原文</param>
        /// <param name="MatchData">节点的数据集合</param>
        /// <returns></returns>
        private List<string> MatchArgumentFocusList(string SourceName, string CC_ParentID, string originalText, List<SYS_CaseCause> MatchData, string paragraphCode)
        {
            List<string> result = new List<string>();
            //获取子争议焦点类型
            List<SYS_CaseCause> sonRows = MatchData.Where(a => a.CC_ParentID == CC_ParentID).ToList();
            foreach (SYS_CaseCause oRow in sonRows)
            {
                string sonArgumentTypeID = LdFormat.ObjectToString(oRow.CC_ID);
                string sonArgumentTypeName = LdFormat.ObjectToString(oRow.CC_Name);
                int cc_NodeType = LdFormat.ObjectToInt(oRow.CC_NodeType);        //结点类型(15:虚拟点；16：争议焦点类型)

                if (cc_NodeType == 15)
                {
                    List<string> secdSonMatchIds = MatchArgumentFocusList(SourceName, sonArgumentTypeID, originalText, MatchData, paragraphCode);
                    //有子级匹配时，返回子级匹配ID；
                    //无子级匹配时，返回当前匹配ID；
                    if (secdSonMatchIds != null && secdSonMatchIds.Any())
                    {
                        foreach (var item in secdSonMatchIds)
                        {
                            if (!result.Contains(item))
                                result.Add(item);
                        }
                    }
                }
                else
                {
                    //获取不同标签下，配置的不同段落来源及相应的提取正则。。
                    IList<MSYS_Express_Source> MSourceArr;
                    MSourceArr = dalRegexSource.GetListArray(sonArgumentTypeID, SourceName, paragraphCode);
                    bool isMatch = false;
                    foreach (MSYS_Express_Source useExtractSource in MSourceArr)
                    {
                        isMatch = (useExtractSource == null) ? false : RuleParseClass.IsMatchs(useExtractSource.CC_RegexInfoCode, originalText);
                    }

                    if (isMatch)
                    {
                        List<string> secdSonMatchIds = MatchArgumentFocusList(SourceName, sonArgumentTypeID, originalText, MatchData, paragraphCode);
                        if (secdSonMatchIds != null && secdSonMatchIds.Any())
                            result.AddRange(secdSonMatchIds);
                        else
                        {
                            result.Add(sonArgumentTypeID);
                        }
                            
                    }
                }
            }
            //无子匹配时，返回空的匹配ID；
            return result;
        }


        /// <summary>
        /// 属性增加方法
        /// </summary>
        /// <param name="AttributeName">属性名称</param>
        /// <param name="AttributeValue">属性值</param>
        /// <param name="dataModel">节点实体</param>
        private void AddAttrAttribute(string AttributeName, string AttributeValue, DataModel dataModel)
        {
            
            AttributeInfo attribute = dataModel.AttributesList.FirstOrDefault(a => a.Name == AttributeName);
            if (attribute == null)
            {
                AttributeInfo attribute1Conent = new AttributeInfo();
                attribute1Conent.Name = AttributeName;
                attribute1Conent.sourceList = new List<Source>();
                Source source = new Source();
                source.SaveValue = AttributeValue;
                source.SourceCode = dataContext.DataLayerAns.SourceCode;
                source.IsCheck = "1";
                attribute1Conent.sourceList.Add(source);
                dataModel.AttributesList.Add(attribute1Conent);
            }
            else
            {
                Source source = attribute.sourceList.FirstOrDefault(a => a.SourceID == dataContext.DataLayerAns.SourceCode);
                if (source == null)
                {
                    Source sources = new Source();
                    sources.SaveValue = AttributeValue;
                    sources.SourceCode = dataContext.DataLayerAns.SourceCode;
                    sources.IsCheck = "1";
                    attribute.sourceList.Add(sources);
                }
                else
                {
                    source.SaveValue = AttributeValue;
                }
            }
        }
    }
}
